package de.neusta.android.generic.implementation;

import com.google.common.base.Preconditions;

import java.lang.reflect.Method;
import java.util.List;

import de.neusta.android.entity.Attribute;
import de.neusta.android.generic.constants.MethodDeclarationType;
import japa.parser.ASTHelper;
import japa.parser.ast.CompilationUnit;
import japa.parser.ast.body.ClassOrInterfaceDeclaration;
import japa.parser.ast.body.FieldDeclaration;
import japa.parser.ast.body.MethodDeclaration;
import japa.parser.ast.body.ModifierSet;
import japa.parser.ast.type.Type;

/**
 * Created by dzebcuks on 24.01.14.
 */
public abstract class AbstractGenerator {

    private CompilationUnit compilationUnit;

    String className;

    String basePackage;

    List<Attribute> attributes;

    private ClassOrInterfaceDeclaration type;

    public String getClassName() {
        return className;
    }

    public String getBasePackage() {
        return basePackage;
    }

    public List<Attribute> getAttributes() {
        return attributes;
    }

    public CompilationUnit getCompilationUnit() {
        return compilationUnit;
    }

    public void setCompilationUnit(CompilationUnit compilationUnit) {
        this.compilationUnit = compilationUnit;
    }

    void createFieldDeclaration(Attribute attribute){
        Type type = null;
        if(attribute.getType().isPrimitive()){
            // todo : find existing primitive type
        } else {
            // todo : create own types?!
        }
        FieldDeclaration fieldDeclaration = ASTHelper.createFieldDeclaration(ModifierSet.PROTECTED, type, attribute.getName());
        ASTHelper.addMember(getClassDeclaration(), fieldDeclaration);
    }

    void createSetter(Attribute attribute){
        createMethodDeclaration(MethodDeclarationType.SETTER, attribute);
    }

    void createGetter(Attribute attribute){
        createMethodDeclaration(MethodDeclarationType.GETTER, attribute);
    }

    private void createMethodDeclaration(MethodDeclarationType methodType, Attribute attribute){
        // Todo : see field declaration
        MethodDeclaration method = new MethodDeclaration(ModifierSet.PUBLIC, ASTHelper.VOID_TYPE, "main");
        method.setModifiers(ModifierSet.addModifier(method.getModifiers(), ModifierSet.STATIC));
        ASTHelper.addMember(getClassDeclaration(), method);
    }

    ClassOrInterfaceDeclaration getClassDeclaration(){
        if(this.type == null){
            Preconditions.checkNotNull(getClassName());
            type = new ClassOrInterfaceDeclaration(ModifierSet.PUBLIC, Boolean.FALSE, getClassName());
        }
        return type;
    }
}
